/*
 ============================================================================
 Name        : client.c
 Author      : Piotr Kowalski & Radek Morytko
 Version     :
 Copyright   : 
 Description : Monitoring client
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <logger.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/queue.h>

#include <signal.h>

#include <common.h>

#define INTERVAL 1

key_t queue_key;
int mqid;

void dispose_message_queue();

void finalize(int signo)
{
	LOG_MSG("Client stop...");
	dispose_message_queue();
	dispose_logger(get_logger());
	exit(EXIT_SUCCESS);
}

void create_message_queue(const char* filename)
{
	LOG_MSG("Creating a message queue");

	queue_key = ftok( filename, (int)getpid() );

	mqid = msgget( queue_key, IPC_CREAT | IPC_EXCL | 0666 );

	if(mqid < 0)
	{
		LOG_MSG("Cannot create a message queue");
		exit(EXIT_FAILURE);
	}

}

void clear_screen()
{
	printf("\E[H\E[2J");
}

void dispose_message_queue()
{
	LOG_MSG("Disposing a message queue");
	if( msgctl( mqid, IPC_RMID, NULL ) < 0 )
	{
		LOG_MSG("Cannot dispose a message queue");
		exit( EXIT_FAILURE );
	}
}

void send_request(pid_t pid)
{
	int req_queue_id;
	struct monitoring_req monitoring_req;

	LOG_MSG("Registering...");

	monitoring_req.interval = INTERVAL;
	monitoring_req.message_queue_key = queue_key;
	monitoring_req.mtype = 1;
	monitoring_req.pid_to_be_monitored = pid;

	key_t k = (key_t)DISPATCHER_KEY;
	req_queue_id = msgget(k, 0);
	if(req_queue_id < 0)
	{
		LOG_MSG("Cannot open a request queue");
		finalize(SIGINT);
	}

	if( msgsnd(req_queue_id, &monitoring_req, sizeof(monitoring_req), 0) < 0 )
	{
		LOG_MSG("Cannot send a request");
		finalize(SIGINT);
	}

	LOG_MSG("Request sent...");
}

void print_header()
{
	printf("************************************************\n");
	printf("* Kowalski & Morytko Memory monitoring system  *\n");
	printf("************************************************\n");
}

void listen_loop()
{
	LOG_MSG("Listening...");
	int latest_message_id = -1;
	ssize_t received_bytes;
	struct monitor_response response;

	while( (received_bytes = msgrcv( mqid, &response, sizeof(response), 0, 0 ) ) > 0 )
	{
		if( latest_message_id != response.message_id )
		{
			clear_screen();
			print_header();
			latest_message_id = response.message_id;
		}

		printf( "%s", response.payload );
		fflush(stdout);
	}
}

int main(int argc, char *argv[]) {

	pid_t pid = NULL_PID;

	if(argc > 2)
	{
		LOG_MSG("usage: client [pid]");
		exit(EXIT_FAILURE);
	}

	LOG_MSG("Client started...");

	/* register signal handler */
	signal(SIGINT, finalize);

	if(argc == 2)
	{
		pid = (pid_t)atoi(argv[1]);
	}

	create_message_queue(argv[0]);
	send_request(pid);
	listen_loop();

	return EXIT_SUCCESS;
}
